home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
DDJMAG
/
DDJ9203.ZIP
/
OOPASM.ZIP
/
LMATH.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-05-08
|
5KB
|
306 lines
.MODEL SMALL
.CODE
;---------------------------------------------------------
; __LngStg - Convert long integer to string.
;
; Entry -
; DX,AX = Long integer.
; ES:DI points to area for string.
;---------------------------------------------------------
Public __LngStg
__LngStg Proc Near
Push Bp
Push Di ;BP+2
Push Es ;BP
Mov Bp,Sp
Mov Si,Dx
Test Dh,80h ;Negative coming in ?
Jz __LngStg0 ;Nope.
Not Dx
Neg Ax
Sbb Dx,-1
__LngStg0:
Sub Bx,Bx
Push Bx ;Set end of string on stack.
LongStg_Lp0:
Push Si
Push Dx
Push Ax
Mov Cx,0
Mov Bx,10
Call ___LDiv ;Long/10.
Pop Bx
Pop Cx
Push Dx ;Save next number to use.
Push Ax
Push Cx ;Save old number.
Push Bx
Mov Cx,0
Mov Bx,10
Call ___LMul
Mov Cx,Dx
Mov Bx,Ax
Pop Ax
Pop Dx
Call ___LSub ;Find the remainder.
Mov Bx,Ax
Pop Ax ;Get next number to use.
Pop Dx
Pop Si
Add BL,'0'
Push Bx ;Save another digit.
Mov Bx,Ax
Or Bx,Dx ;Result 0 yet ?
Jnz LongStg_Lp0 ;Nope, so go back up.
;
; The number is broken down, so let's assemble a string.
;
Mov Di,[Bp][2] ;Load ES:DI with destination.
Mov Es,[Bp]
Cld
Test Si,8000h ;Negative ?
Jz LongStg_Pos ;Nope, so jump.
Mov AL,'-'
Stosb ;Set minus sign into string.
LongStg_Pos:
LongStg_Lp1:
Pop Ax
Stosb
Or Al,Al
Jnz LongStg_Lp1
Mov Sp,Bp
Pop Es
Pop Di
Pop Bp
Ret
__LngStg Endp
;------------------------- LOW LEVEL MATH ROUTINES ------------------------
;
;--------------------------
; ___Ladd - Add DX,AX to CX,BX, return DX,AX
; ___LSub - Sub CX,BX from DX,AX return DX,AX
;--------------------------
Public ___Ladd,___LSub
___LSub Proc Near
Push Ax
Mov Ax,0
Sub Ax,Bx ;Negate CX,BX.
Mov Bx,Ax
Mov Ax,0
Sbb Ax,Cx
Mov Cx,Ax
Pop Ax
___Ladd:
Add Ax,Bx
Adc Dx,Cx
Ret
___LSub Endp
;--------------------------
; ___LMul - Long integer multiplier
;--------------------------
Public ___LMul
___LMul Proc Near
Push Si
Push Di
Push Bp
Sub Bp,Bp
;
; Check signs
;
Test Dh,80h ;Op A neg ?
Jz ___LMul_PA
Not Bp
Mov Si,0
Sub Si,Ax
Mov Ax,Si
Mov Si,0
Sbb Si,Dx
Mov Dx,Si
___LMul_PA:
Test Ch,80h ;Op B neg ?
Jz ___LMul_PB
Not Bp
Mov Si,0
Sub Si,Bx
Mov Bx,Si
Mov Si,0
Sbb Si,Cx
Mov Cx,Si
___LMul_PB:
Mov Si,Dx
Mov Di,Ax
Mul Bx
Push Ax
Push Dx
Mov Ax,Si
Mul Bx
Pop Bx
Add Ax,Bx
Adc Dx,0
Push Ax
Mov Bx,Dx
Mov Ax,Di
Mul Cx
Pop Di
Add Di,Ax
Push Di
Mov Di,0
Adc Bx,Dx
Adc Di,0
Mov Ax,Si
Mul Cx
Add Ax,Bx
Adc Dx,Di
Pop Cx
Pop Bx
Or Ax,Dx
Mov Ax,Bx
Mov Dx,Cx
Pushf
Test Bp,Bp
Jz ___LMul_RP
Mov Bx,0
Sub Bx,Ax
Mov Ax,Bx
Mov Bx,0
Sbb Bx,Dx
Mov Dx,Bx
___LMul_RP:
Popf
Pop Bp
Pop Di
Pop Si
Jz ___LMul_Dne
Stc
___LMul_Dne:
Ret
___LMul Endp
;--------------------------
; ___LDiv - Divide
;
; OpA = DX,AX (DX=msw)
; OpB = CX,BX (CX=msw)
;
; A/B -> Destination (DX,AX - DX=msw)
;--------------------------
Public ___LDiv
___LDiv Proc Near
Push Bp
Sub Sp,4
Mov Bp,Sp
Mov [Bp],Cx
Or Cx,Bx
Jnz __LD0 ;Jump if operand B is not 0.
Sub Ax,Ax ;If so, then return 0.
Mov Dx,Ax
Jmp __LD_Exit
__LD0:
Mov [Bp+2],Dx
Or Dx,Ax
Jnz __LD1 ;Jump if operand A is not 0.
Jmp __LD_Exit
__LD1:
Mov Cx,[Bp]
Mov Dx,[Bp+2]
Mov Si,Dx
Test Si,Si
Jns __LD2 ;Jump if op A is positive.
Not Dx
Neg Ax
Sbb Dx,-1
__LD2:
Xor Si,Cx
Mov [BP],Si ;Save a sign flag.
Sub Si,Si
Test Ch,Ch
Jns __LD3 ;Jump if op B is positive.
Not Cx
Neg Bx
Sbb Cx,-1
__LD3:
Jnz __LD6
Test Bx,Bx
Js __LD6
Mov Di,20h
__LD4:
Shl Ax,1
Rcl Dx,1
Rcl Si,1
Cmp Si,Bx
Jb __LD5
Sub Si,Bx
Inc Ax
__LD5:
Dec Di
Jnz __LD4
Sub Cx,Cx
Mov Bx,Si
Jmp __Lda
__LD6:
Mov Di,0010h
__LD7:
Shl Ax,1
Rcl Dx,1
Rcl Si,1
Cmp Si,Cx
Jb __LD9
Jnz __LD8
Cmp Dx,Bx
Jb __LD9
__LD8:
Sub Dx,Bx
Sbb Si,Cx
Inc Ax
__LD9:
Dec Di
Jnz __LD7
Mov Cx,Si
Mov Bx,Dx
Sub Dx,Dx
__LDA:
Test Word Ptr [BP],8000h
Jz __LDB
Not Dx
Neg Ax
Sbb Dx,-1
__LDB:
Test Word Ptr [BP+2],8000h
Jz __LD_Exit
Not Cx
Neg Bx
Sbb Cx,-1
__LD_Exit:
Add Sp,4
Pop Bp
Ret
___LDiv Endp
END